module uart_byte_rx(
    Clk,
    Reset_n,
    uart_rx,
    Rx_Done,
    Rx_Data
);

    input Clk;
    input Reset_n;
    input uart_rx;
    output reg Rx_Done;
    output reg [7:0] Rx_Data;

    reg en_baud_cnt;
    reg [3:0] bit_cnt;
    reg r_uart_rx;
    reg dff0_uart_rx;
    reg dff1_uart_rx;
    reg [29:0] baud_div_cnt;
    reg [3:0] oversample_cnt; // Oversampling counter
    reg [1:0] sampled_uart_rx; // Sampled values for majority voting

    parameter CLOCK_FREQ = 50_000_000;
    parameter BAUD = 9600;
    parameter OVERSAMPLE = 16; // 16x oversampling
    parameter MCNT_BAUD = CLOCK_FREQ / (BAUD * OVERSAMPLE) - 1; // Adjusted baud rate count

    wire nedge_uart_rx;
    wire w_Rx_Done;

    // Detect negative edge of UART RX (start bit)
    assign nedge_uart_rx = (dff1_uart_rx == 0) && (r_uart_rx == 1);
    assign w_Rx_Done = (oversample_cnt == OVERSAMPLE/2) && (bit_cnt == 9);

    // Baud counter logic with oversampling
    always @(posedge Clk or negedge Reset_n)
    if (!Reset_n)
        baud_div_cnt <= 0;
    else if (en_baud_cnt) begin
        if (baud_div_cnt == MCNT_BAUD)
            baud_div_cnt <= 0;
        else
            baud_div_cnt <= baud_div_cnt + 1'd1;
    end
    else
        baud_div_cnt <= 0;

    // UART edge detection logic
    always @(posedge Clk) begin
        dff0_uart_rx <= uart_rx;
        dff1_uart_rx <= dff0_uart_rx;
    end

    always @(posedge Clk)
        r_uart_rx <= dff1_uart_rx;

    // Enable baud counter logic
    always @(posedge Clk or negedge Reset_n)
    if (!Reset_n)
        en_baud_cnt <= 0;
    else if (nedge_uart_rx)
        en_baud_cnt <= 1;
    else if ((oversample_cnt == OVERSAMPLE/2) && (bit_cnt == 0) && (dff1_uart_rx == 1))
        en_baud_cnt <= 0;
    else if ((oversample_cnt == OVERSAMPLE/2) && (bit_cnt == 9))
        en_baud_cnt <= 0;

    // Oversample counter logic
    always @(posedge Clk or negedge Reset_n)
    if (!Reset_n)
        oversample_cnt <= 0;
    else if (baud_div_cnt == MCNT_BAUD) begin
        if (oversample_cnt == OVERSAMPLE - 1)
            oversample_cnt <= 0;
        else
            oversample_cnt <= oversample_cnt + 1;
    end

    // Bit counter logic
    always @(posedge Clk or negedge Reset_n)
    if (!Reset_n)
        bit_cnt <= 0;
    else if ((oversample_cnt == OVERSAMPLE/2) && (bit_cnt == 9))
        bit_cnt <= 0;
    else if (baud_div_cnt == MCNT_BAUD && oversample_cnt == OVERSAMPLE - 1)
        bit_cnt <= bit_cnt + 1'd1;

    // Bit reception logic with oversampling (majority voting)
    always @(posedge Clk or negedge Reset_n)
    if (!Reset_n)
        Rx_Data <= 8'b0;
    else if (baud_div_cnt == MCNT_BAUD/2) begin
        // Perform majority voting using 2 samples
        sampled_uart_rx <= {sampled_uart_rx[0], dff1_uart_rx};
        case(bit_cnt)
            1: Rx_Data[0] = (sampled_uart_rx[1] & sampled_uart_rx[0]);
            2: Rx_Data[1] = (sampled_uart_rx[1] & sampled_uart_rx[0]);
            3: Rx_Data[2] = (sampled_uart_rx[1] & sampled_uart_rx[0]);
            4: Rx_Data[3] = (sampled_uart_rx[1] & sampled_uart_rx[0]);
            5: Rx_Data[4] = (sampled_uart_rx[1] & sampled_uart_rx[0]);
            6: Rx_Data[5] = (sampled_uart_rx[1] & sampled_uart_rx[0]);
            7: Rx_Data[6] = (sampled_uart_rx[1] & sampled_uart_rx[0]);
            8: Rx_Data[7] = (sampled_uart_rx[1] & sampled_uart_rx[0]);
            default: Rx_Data <= Rx_Data;
        endcase
    end

    // Rx_Done signal
    always @(posedge Clk)
        Rx_Done <= w_Rx_Done;

endmodule
